#include "hwdrv.h"
#include <string.h>
#include "config.h"
#include "jkutil/configparser.h"
#include "log/zlog.hh"

#define HWDRV_ERR(fmt, ...) zlog()->error("[HWDRV] " fmt, ##__VA_ARGS__)
#define HWDRV_INFO(fmt, ...) zlog()->info("[HWDRV] " fmt, ##__VA_ARGS__)

using namespace hwdrv;
using namespace std;
using Util::ConfigParser;

HwMgr& HwMgr::get()
{
    static HwMgr mgr;
    return mgr;
}

HwMgr::HwMgr()
{
    cfg_file_ = string(ZUC_DEFAULT_CONFIG_DIR) + "/cab/cab2.xml";
    name_ = "CabV2_SIM";
    is_sim_ = true;
    type_ = 2;

    lan_ports_.clear();
    com_ports_.clear();
    rob_slots_.clear();
    scb_slot_.devid = 0;
    scb_slot_.bus.type = "sim";
    scb_slot_.bus.interface = "";
}
int HwMgr::init(uint8_t cabtype, int is_vm)
{
    //解析对应的设备配置文件
    string dev_cfg_file = string(ZUC_DEFAULT_CONFIG_DIR) + "/cab/Cab" + to_string(cabtype) + ".xml";
    ConfigParser p(dev_cfg_file.c_str());
    bool simflag = false;
    if (!p.is_valid())
    {
        //设备配置文件无效，使用默认配置cabv2，并标记为sim设备
        string default_dev = string(ZUC_DEFAULT_CONFIG_DIR) + "/cab/cab2.xml";
        is_sim_ = true;
        type_ = 2;
        name_ = "CabV2_UN";
        cfg_file_ = default_dev;
        p = ConfigParser(default_dev.c_str());
    }
    else
    {
        cfg_file_ = dev_cfg_file;
        type_ = cabtype;
        p.get("info.name", name_, true);
        if (is_vm == -1)
        {
            p.get("info.sim", is_sim_, true);
        }
        else
        {
            is_sim_ = is_vm ? true : false;
        }
    }
    HWDRV_INFO("Load {} info. Type:{} Sim:{}", name_, type_, is_sim_);
    load_scb(&p);
    load_rob(&p);
    load_lan(&p);
    load_com(&p);
    return 0;
}
int HwMgr::load_bus(void* pp, int index, HwMgr::BusInfo& bus)
{
    auto p = (ConfigParser*)pp;
    auto bus_str = ConfigParser::str_append_index("bus", index);
    if (p->get(bus_str + ".type", bus.type, true))
    {
        bus.type = "sim";
        bus.interface = "";
        bus.name = "sim";
        return -1;
    }
    p->get(bus_str + ".interface", bus.interface, true);
    int id = 0;
    p->get(bus_str + ".id", id, true);
    bus.name = bus.type + to_string(id);
    return 0;
}
int HwMgr::load_scb(void* pp)
{
    scb_slot_.type = type_;
    auto p = (ConfigParser*)pp;
    int scb_bus = 1;
    p->get("scb.bus", scb_bus, true);
    if (load_bus(pp, scb_bus, scb_slot_.bus))
    {
        HWDRV_ERR("scb bus not found, so use {} bus", scb_slot_.bus.type);
    }
    p->get("scb.devid", scb_slot_.devid, true);
    HWDRV_INFO("Load {} scb info. Devid:{}. Bus:{} {}", name_, scb_slot_.devid, scb_slot_.bus.name, scb_slot_.bus.interface);
    return 0;
}
int HwMgr::load_rob(void* pp)
{
    auto p = (ConfigParser*)pp;
    for (int i = 0; i < 2; i++)
    {
        RobSlotInfo rob;
        rob.devid = 0;
        rob.slot_index = i;
        auto rob_str = ConfigParser::str_append_index("rob", i);
        int bus_index = i;
        if (p->get(rob_str + ".bus", bus_index, true))
        {
            break;
        }
        if (load_bus(pp, bus_index, rob.bus))
        {
            HWDRV_ERR("rob bus not found, so use {} bus", rob.bus.type);
        }
        p->get(rob_str + ".devid", rob.devid, true);
        rob.slot_index = i;
        HWDRV_INFO("Load {} rob {} info. Devid:{}. Bus:{} {}", name_, rob.slot_index, rob.devid, rob.bus.name, rob.bus.interface);
        rob_slots_.push_back(rob);
    }
    return 0;
}
int HwMgr::load_lan(void* pp)
{
    auto p = (ConfigParser*)pp;
    for (int i = 0; i < 6; i++)
    {
        auto net_str = ConfigParser::str_append_index("lan", i);
        int id = -1;
        if (p->get(net_str + ".id", id, true))
        {
            break;
        }
        auto lan = make_shared<LanPort>(p, net_str);
        HWDRV_INFO("Load {} {} info. Adapter:{}", name_, lan->get_name(), lan->get_adapter());
        lan_ports_.push_back(lan);
    }
    return 0;
}
int HwMgr::load_com(void*)
{
    //
    return 0;
}